package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.ehs.dto.unit.EhsUnitDto;
import qc.module.ehs.dto.unitcategory.TplUnitCategoryDto;
import qc.module.ehs.dto.unitcategory.TplUnitCategoryTreeTableItemDto;
import qc.module.ehs.dto.unitcategory.UnitCategoryHazardItemsSetDto;
import qc.module.ehs.entity.EhsTplUnitcategory;
import qc.module.ehs.entity.EhsTplUnitcategoryHazards;
import qc.module.ehs.mapper.EhsTplUnitcategoryMapper;
import qc.module.ehs.repository.EhsTplUnitcategoryRepository;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 单元分类接口Service
 *
 * @author QuCheng Tech
 * @create 2024/5/22
 */
@Service
public class EhsTplUnitcategoryService {
    
    private EhsTplUnitcategoryRepository repository;

    @Autowired
    public void setRepository(EhsTplUnitcategoryRepository repository) {
        this.repository = repository;
    }

    @Autowired
    private EhsUnitInfoService unitBasicService;
    
    @Autowired
    private EhsTplUnitcategoryHazardsService unitcategoryHazardsService;
    
    @Autowired
    private EhsTplHazarditemService hazarditemService;

    /**
     * 获取单元分类，以TreeTable树型形式返回数据
     *
     * @return List<TplUnitCategoryTreeTableItemDto>
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    public List<TplUnitCategoryTreeTableItemDto> queryTreeTable(){
        //1.查询所有单元分类
        LambdaQueryWrapper<EhsTplUnitcategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(EhsTplUnitcategory::getUccd);
        List<EhsTplUnitcategory> ens = repository.selectList(wrapper);
        
        if (CollectionUtils.isEmpty(ens)) return null;
        
        //2.ens转换为TreeTableItemDto
        List<TplUnitCategoryTreeTableItemDto> dtos = EhsTplUnitcategoryMapper.MAPPER.toTreeTableItemDtoList(ens);
        
        List<TplUnitCategoryTreeTableItemDto> result = new ArrayList<>();
        
        //3.获取一级单元分类
        List<TplUnitCategoryTreeTableItemDto> rootCategories = dtos.stream().filter(p -> StringUtils.isEmpty(p.getPuccd())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(rootCategories)){
            result = getSubCategories(dtos,rootCategories);
        }
        
        return result;
    }

    /**
     * 递归获取子级单元分类信息
     * 
     * @param dtos 所有单元分类
     * @param pCategories 父级单元分类
     * @return List<TplUnitCategoryTreeTableItemDto>
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    private List<TplUnitCategoryTreeTableItemDto> getSubCategories(List<TplUnitCategoryTreeTableItemDto> dtos,List<TplUnitCategoryTreeTableItemDto> pCategories){
        List<TplUnitCategoryTreeTableItemDto> result = new ArrayList<>();
        
        if (CollectionUtils.isEmpty(dtos)) return null;
        
        if (CollectionUtils.isNotEmpty(pCategories)){
            for (TplUnitCategoryTreeTableItemDto pCategory : pCategories){
                //获取子级分类
                List<TplUnitCategoryTreeTableItemDto> subCategories = dtos.stream().filter(p -> pCategory.getUccd().equals(p.getPuccd())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(subCategories)){
                    getSubCategories(dtos,subCategories);
                    pCategory.setChildren(subCategories);
                }
                result.add(pCategory);
            }
        }
        return result;
    }

    /**
     * 获取指定 - 同时支持@RequestParam和@PathVariable方式
     * @param id 单元分类代码
     * @return TplUnitCategoryDto
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    public TplUnitCategoryDto get(String id) throws QCPromptException {
        if (StringUtils.isBlank(id)) throw new QCPromptException("单元分类代码不能为空");
        
        EhsTplUnitcategory en = repository.selectById(id);
        if (Objects.nonNull(en)){
            return EhsTplUnitcategoryMapper.MAPPER.toDto(en);
        }
        return null;
    }

    /**
     * 新增指定单元分类
     *
     * @param dto 单元分类信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    public String add(TplUnitCategoryDto dto){
        //1.对象判断
        if (dto == null) return QCUnifyReturnValue.Warn("单元分类信息不能为空");
        if (StringUtils.isBlank(dto.getUccd())) return QCUnifyReturnValue.Warn("单元分类代码不能为空");
        if (StringUtils.isBlank(dto.getUcnm())) return QCUnifyReturnValue.Warn("单元分类名称不能为空");
        if (StringUtils.isBlank(dto.getUctype())) return QCUnifyReturnValue.Warn("单元类型标记不能为空");
        if (dto.getIsconstruction() == null) return QCUnifyReturnValue.Warn("是否为在建工程不能为空");
        if (StringUtils.isBlank(dto.getHdbcd())) return QCUnifyReturnValue.Warn("导则库代码不能为空");

        //2.判断新增对象是否已经存在，存在则提示
        if (isExist(dto.getUccd())) return QCUnifyReturnValue.Warn("单元分类代码已经存在");
        
        //3.有上级单元分类时判断上级单元分类是否存在，不存在则提示
        if (StringUtils.isNotBlank(dto.getPuccd())){
            if (!isExist(dto.getPuccd())) return QCUnifyReturnValue.Warn("上级单元分类代码不存在或已删除");
        }
        
        //4.dto -> entity
        EhsTplUnitcategory en = EhsTplUnitcategoryMapper.MAPPER.dtoToEntity(dto);
        
        //5.保存数据
        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("保存失败");
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改指定单元分类
     *
     * @param dto 单元分类信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    public String update(TplUnitCategoryDto dto){
        //1.对象判断
        if (dto == null) return QCUnifyReturnValue.Warn("单元分类信息不能为空");
        if (StringUtils.isBlank(dto.getUccd())) return QCUnifyReturnValue.Warn("单元分类代码不能为空");
        if (StringUtils.isBlank(dto.getUcnm())) return QCUnifyReturnValue.Warn("单元分类名称不能为空");
        if (StringUtils.isBlank(dto.getUctype())) return QCUnifyReturnValue.Warn("单元类型标记不能为空");
        if (dto.getIsconstruction() == null) return QCUnifyReturnValue.Warn("是否为在建工程不能为空");
        if (StringUtils.isBlank(dto.getHdbcd())) return QCUnifyReturnValue.Warn("导则库代码不能为空");

        //2.判断对象是否存在，不存在则提示
        if (!isExist(dto.getUccd())) return QCUnifyReturnValue.Warn("单元分类代码不存在");

        //3.有上级单元分类时判断上级单元分类是否存在，不存在则提示
        if (StringUtils.isNotBlank(dto.getPuccd())){
            if (!isExist(dto.getPuccd())) return QCUnifyReturnValue.Warn("上级单元分类代码不存在");
        }

        //4.dto -> entity
        EhsTplUnitcategory en = EhsTplUnitcategoryMapper.MAPPER.dtoToEntity(dto);

        //5.保存数据
        repository.updateById(en);

        //同步修改该单元分类下的单元信息：是否为在建工程
        List<EhsUnitDto> unitDtos = unitBasicService.getUnitByCategoryCode(en.getUccd());
        if (CollectionUtils.isNotEmpty(unitDtos)){
            for (EhsUnitDto unitDto : unitDtos){
                unitDto.setIsconstruction(en.getIsconstruction());
                unitBasicService.update(unitDto);
            }
        }
        
        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除指定分类单元
     *
     * @param id 单元分类代码
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    public String delete(String id){
        if (StringUtils.isBlank(id)) return QCUnifyReturnValue.Warn("单元分类代码不能为空");
        
        //判断单元分类下是否有单元信息，有则不允许删除
        List<EhsUnitDto> unitDtos = unitBasicService.getUnitByCategoryCode(id);
        if (CollectionUtils.isNotEmpty(unitDtos)) return QCUnifyReturnValue.Warn("该分类下有单元信息，请先删除单元信息");
        
        //判断单元分类下是否有子级分类，有则不允许删除
        LambdaQueryWrapper<EhsTplUnitcategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(EhsTplUnitcategory::getUccd);
        wrapper.eq(EhsTplUnitcategory::getPuccd,id);
        List<EhsTplUnitcategory> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) return QCUnifyReturnValue.Warn("该分类下有子级分类，请先删除子级分类信息");

        repository.deleteById(id);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 设置单元分类危险源清单关联关系
     *
     * @param dto
     * @return 成功返回null，失败返回错误或提示信息
     * @aythor QuCheng Tech
     * @since 2024/8/13
     */
    public String setHazardItems(UnitCategoryHazardItemsSetDto dto){
        if (dto == null) return QCUnifyReturnValue.Warn("设置条件不能为空");
        if (StringUtils.isBlank(dto.getUccd())) return QCUnifyReturnValue.Warn("单元分类ID不能为空");
        
        //判断单元分类是否存在
        if (!isExist(dto.getUccd())) return QCUnifyReturnValue.Warn("单元分类代码不存在");
        
        //删除指定单元分类与危险源清单的关联关系
        unitcategoryHazardsService.deleteByUccd(dto.getUccd());

        //如果有设置关联信息，逐个进行添加
        if (CollectionUtils.isNotEmpty(dto.getHicds())){
            for (String hicd : dto.getHicds()){
                //先判断危险源清单ID是否存在，存在的设置关联关系
                if (hazarditemService.hicdIsExist(hicd)){
                    unitcategoryHazardsService.add(dto.getUccd(),hicd);
                }
            }
        }
        
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定单元分类的关联危险源清单ID集合
     *
     * @param uccd 单元分类代码
     * @return 关联的危险源清单ID集合
     * @author QuCheng Tech
     * @since 2024/8/13
     */
    public List<String> getHazardItemIds(String uccd) throws QCPromptException {
        if (StringUtils.isBlank(uccd)) throw new QCPromptException("单元分类代码不能为空");
        
        List<String> result = new ArrayList<>();
        
        List<EhsTplUnitcategoryHazards> ens = unitcategoryHazardsService.selectByUccd(uccd);
        if (CollectionUtils.isNotEmpty(ens)){
            for (EhsTplUnitcategoryHazards en : ens){
                result.add(en.getHicd());
            }
        }
        
        return result;
    }

    /**
     * 判断单元分类代码是否存在
     *
     * @param id 单元分类代码
     * @return 存在返回true，否则返回false
     * @author QuCheng Tech
     * @since 2024/5/22
     */
    public boolean isExist(String id) {
        EhsTplUnitcategory en = repository.selectById(id);
        if (Objects.nonNull(en)) {
            return true;
        }
        return false;
    }

    /***
     * 获取所有单元分类集合，返回实体类信息
     *
     * @return java.util.List<qc.module.ehs.entity.EhsTplUnitcategory>
     * @author QuCheng Tech
     * @since 2025/1/15
     */
    public List<EhsTplUnitcategory> getAll() {
        LambdaQueryWrapper<EhsTplUnitcategory> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(EhsTplUnitcategory::getUccd);
        List<EhsTplUnitcategory> ens = repository.selectList(wrapper);

        return ens;
    }
}
